﻿using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v2;
using Google.Apis.Drive.v2.Data;
using Google.Apis.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace WotModSync
{
    public class GoogleDrive
    {

        public static string GetSourcePathValue(File f)
        {
            string sourcePath = string.Empty;
            if (f.Properties == null || f.Properties.Count(pr => pr.Key == GoogleDrive.PropertySourcePath) == 0)
            {
                return string.Empty;
            }

            sourcePath = f.Properties.Single(pr => pr.Key == GoogleDrive.PropertySourcePath).Value.Replace("+", "\\");
            return sourcePath;
        }
        public const string PropertyModPackName = "modPackName";
        public const string PropertySourcePath = "sourcePath";


        private DriveService driveService;
        private string modPackName;
        private File googleModRoot;

        public GoogleDrive(string modPackName)
        {
            driveService = GoogleUtils.Authenticate();
            this.modPackName = modPackName;
        }

        public File GetOrCreateModPackDirectory()
        {

            var list = GoogleUtils.GetFiles(driveService, "mimeType = 'application/vnd.google-apps.folder' and 'root' in parents and trashed=false and properties has { key='" + PropertyModPackName + "' and value='" + modPackName + "' and visibility='PRIVATE' }");

            if (list.Count() == 0)
            {
                this.googleModRoot = GoogleUtils.CreateDirectory(driveService, modPackName, "root", new Property[] { new Property() { Key = PropertyModPackName, Value = modPackName, Visibility = "PRIVATE" } });
            }
            else
            {
                this.googleModRoot = list[0];
            }

            return googleModRoot;
        }

        public File GetModPackDirectory()
        {

            var list = GoogleUtils.GetFiles(driveService, "mimeType = 'application/vnd.google-apps.folder' and 'root' in parents and trashed=false and properties has { key='" + PropertyModPackName + "' and value='" + modPackName + "' and visibility='PRIVATE' }");

            if (list.Count() == 0)
            {
                return null;
            }
            else
            {
                this.googleModRoot = list[0];
            }

            return googleModRoot;
        }


        private IList<File> GetFiles(string search)
        {
            return GoogleUtils.GetFiles(driveService, search);
        }


        public List<string> GetModPacks()
        {
            var list = new List<string>();
            foreach (Google.Apis.Drive.v2.Data.File f in this.GetFiles("mimeType = 'application/vnd.google-apps.folder' and 'root' in parents and trashed=false"))
            {

                string sharing = string.Empty;

                var permissionsList = GoogleUtils.GetPermissionsOnFile(driveService, f.Id);

                if (permissionsList != null)
                {
                    foreach (var p in permissionsList.Where(per => per.EmailAddress != Properties.Settings.Default.ServiceAccountEmail))
                    {
                        sharing += p.EmailAddress + ";";
                    }
                    sharing = sharing.TrimEnd(';');
                }

                if (string.IsNullOrEmpty(sharing))
                {
                    sharing = "none";
                }


                list.Add(string.Format("{0} (Sharing:{1})", f.Title, sharing));
            }
            return list;
        }


        public List<string> GetModPackFileNames()
        {
            var list = new List<string>();
            foreach (Google.Apis.Drive.v2.Data.File f in this.GetFiles("properties has { key='" + GoogleDrive.PropertyModPackName + "' and value='" + modPackName + "' and visibility='PRIVATE' }"))
            {
                string sourcePath = string.Empty;
                if (f.Properties != null && f.Properties.Count(pr => pr.Key == GoogleDrive.PropertySourcePath) > 0)
                {
                    sourcePath = f.Properties.Single(pr => pr.Key == GoogleDrive.PropertySourcePath).Value;
                }

                list.Add(sourcePath.Replace("+", "\\"));
            }
            return list;
        }


        public List<File> GetModPackFiles()
        {
            var list = new List<File>();
            foreach (Google.Apis.Drive.v2.Data.File f in this.GetFiles("properties has { key='" + GoogleDrive.PropertyModPackName + "' and value='" + modPackName + "' and visibility='PRIVATE' } and mimeType != 'application/vnd.google-apps.folder'"))
            {
                list.Add(f);
            }
            return list;
        }


        public void DeleteAllModPackFiles()
        {
            foreach (File f in GoogleUtils.GetFiles(driveService, "properties has { key='" + PropertyModPackName + "' and value='" + modPackName + "' and visibility='PRIVATE' }"))
            {
                GoogleUtils.DeleteFile(driveService, f);
            }
        }

        public void UploadFile(System.IO.FileInfo file, string wotDirectory)
        {
            GoogleUtils.UploadFile(driveService, file.FullName, this.googleModRoot.Id, new Property[] { new Property() { Key = PropertyModPackName, Value = modPackName, Visibility = "PRIVATE" }, new Property() { Key = PropertySourcePath, Value = PathUtils.ReplaceBackslash(PathUtils.RemoveWotDirectoryFromPath(file.FullName, wotDirectory)), Visibility = "PRIVATE" } });
        }

        public void DownloadFile(File f, string destinationPath)
        {
            GoogleUtils.DownloadFile(driveService, f, destinationPath);
        }

        public void DeleteFile(File f)
        {
            GoogleUtils.DeleteFile(driveService, f);
        }

        public void UpdateProperty(String fileId, String key, String newValue, String visibility)
        {
            GoogleUtils.UpdateProperty(driveService, fileId, key, newValue, visibility);
        }

        public void RenameFile(String fileId, String newTitle)
        {
            GoogleUtils.RenameFile(driveService, fileId, newTitle);
        }

        public void ShareFile(string fileId, string email, string role)
        {
            GoogleUtils.ShareFile(driveService, fileId, email, role);
        }

        public IList<Permission> GetPermissionsOnFile(String fileId)
        {
            return GoogleUtils.GetPermissionsOnFile(driveService, fileId);
        }

        public void DeletePermission(String fileId, string permissionId)
        {
            GoogleUtils.DeletePermission(driveService, fileId, permissionId);
        }
    }
}
